package com.jiao.service.impl;

import com.jiao.domain.LoginUser;
import com.jiao.domain.Result;
import com.jiao.domain.VO.LikeListVo;
import com.jiao.domain.VO.LikeVo;
import com.jiao.domain.entity.LikeArticle;
import com.jiao.mapper.LikeArticleMapper;
import com.jiao.service.LikeService;
import com.jiao.utils.RedisKeyUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jiao.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class LikeServiceImp implements LikeService {
    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Autowired
    LikeArticleMapper likeArticleMapper;

    /*
    * 对该文章进行点赞操作
    * */
    public Result<LikeVo> like(Long articleId) {
        //获取当前用户id
        Long userId = SecurityUtils.getLoginId();

        //点赞操作
        Boolean ismember = likeClick(articleId, userId);
        //查看已有多少人点赞
        Long num = likeNumber(articleId);

        return Result.success(new LikeVo(num,ismember));
    }

    @Override
    public Result<List<LikeListVo>> selectAllLiker(Long articleId) {
        //文章点击人集合员
        String articleLikerKey = RedisKeyUtil.getArticleLikerKey(articleId);
        Map<String,String> likeArticlesMap = new HashMap<>();

        //判断redis有无该文章的点赞数据，如果不存在，则查找数据库中所有关于该文章的点赞记录
        if(Objects.equals(likerIsHasKey(articleId),false)){
            List<LikeArticle> likeArticles = likeArticleMapper.selectList(new LambdaQueryWrapper<LikeArticle>().eq(LikeArticle::getArticleId, articleId));
            //数据库中点赞数据不为空，那就提取数据库中数据放入缓存中
            if(!likeArticles.isEmpty()){
                likeArticles.forEach( likeArticle -> likeArticlesMap.put(String.valueOf(likeArticle.getUserId()),likeArticle.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
                redisTemplate.opsForHash().putAll(RedisKeyUtil.getArticleLikerKey(articleId),likeArticlesMap);
            }
        }
        Map<Object, Object> entries = redisTemplate.opsForHash().entries(articleLikerKey);
        //遍历map集合，取出元素
        List<LikeListVo> likeListVos= new LinkedList<>();
        entries.forEach((key, value) -> likeListVos.add(new LikeListVo(key.toString(), value.toString())));
        return Result.success(likeListVos);
    }

    /*
    * 点赞操作的具体实施细节
    * */
    private Boolean likeClick(Long articleId, Long userId) {
        //文章点击人集合员
        String articleLikerKey = RedisKeyUtil.getArticleLikerKey(articleId);
        Map<String,String> likeArticlesMap = new HashMap<>();

        //判断redis有无该文章的点赞数据，如果不存在，则查找数据库中所有关于该文章的点赞记录
        if(Objects.equals(likerIsHasKey(articleId),false)){
            List<LikeArticle> likeArticles = likeArticleMapper.selectList(new LambdaQueryWrapper<LikeArticle>().eq(LikeArticle::getArticleId, articleId));
            //数据库中点赞数据不为空，那就提取数据库中数据放入缓存中
            if(!likeArticles.isEmpty()){
                likeArticles.forEach( likeArticle -> likeArticlesMap.put(String.valueOf(likeArticle.getUserId()),likeArticle.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
                redisTemplate.opsForHash().putAll(RedisKeyUtil.getArticleLikerKey(articleId),likeArticlesMap);
            }
        }

        //判断该文章是否被该用户点赞
        Boolean ismember = likerIsMumber(articleId,userId);

        //处理redis中数据
        if(Objects.equals(ismember,true)){
            redisTemplate.opsForHash().delete(articleLikerKey,String.valueOf(userId));
        }else{
            redisTemplate.opsForHash().put(articleLikerKey,String.valueOf(userId), LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) );
        }

        return !ismember;
    }

    /*
    * 获取文章总点击量
    * */
    private Long likeNumber(Long articleId){
        //文章总点击量Key
        String articleLikeNumKey = RedisKeyUtil.getArticleLikerKey(articleId);
        return redisTemplate.opsForHash().size(articleLikeNumKey);
    }

    /*
    * 判断该文章是否被该用户点赞
    * */
    private Boolean likerIsMumber(Long articleId,Long userId){
        //文章点击人员集合，文章set集合
        String articleLikerKey = RedisKeyUtil.getArticleLikerKey(articleId);

        return redisTemplate.opsForHash().hasKey(articleLikerKey, String.valueOf(userId));
    }

    /*
     * 判断缓存中是否已经加载了该文章的点赞集合（键值对数据）
     * */
    private Boolean likerIsHasKey(Long articleId){
        //文章点击人员集合，文章set集合
        String articleLikerKey = RedisKeyUtil.getArticleLikerKey(articleId);

        return redisTemplate.hasKey(articleLikerKey);
    }

}
